package patternmining.model.construction;

import patternmining.model.construction.ModelData;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import patternmining.model.graph.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import patternmining.model.construction.Source;

/** Constructs a graph that models the received source (constructor parameter) as a abstraction following the BPSL-Formalism  
 *  The graph constructed is a computational representation of the BPSL-Formula encountered in the Source.
 * 
 *  Sources might be:
 *  -> BPSL formula specifications (instances of class BPSLSourceFile)
 *  -> Java Source code of a project (instances of class JavaSourceGroup) 
 * 
 * @see BPSLSourceFile.java
 * @see JavaSouceGroup.java
 * @version 1.0, 06.05.2008
 * @author Holger Wiehen
 */
public class ModelGraphBuilder {
   
   private Source source;
   private int edgeCount;
   private int vertexCount;
   private DirectedSparseGraph<Vertex, Edge> graph;
   private Map<String, Vertex> insertedVertices;
   private SourceReference sourceRef;
   
   /**
    * 
    * @param source  the source that shall be modeled with a graph
    */
   public ModelGraphBuilder(Source source){
        this.source = source;
        edgeCount = 0;
        vertexCount = 0;
        graph = new DirectedSparseGraph<Vertex, Edge>();
        insertedVertices = new HashMap<String, Vertex>();
        sourceRef= new SourceReference();
   }
   
   /** Obtain the graph that representes computationaly the BPSL formula encountered
    * in the source.
    * 
    * @return
    */
   public DirectedSparseGraph<Vertex, Edge> getGraph(){
       TermData vData;
       AtomData eData;
       //add all vertices to the graph
       ModelData modelData = source.modelData();
       Iterator<TermData> vDataIt = modelData.termDataIterator();
       while( vDataIt.hasNext() ){
           vData = vDataIt.next();
           this.addVertex(vData.name(), vData.type() );
       }
       //add all edges to the graph
       Iterator<AtomData> eDataIt = modelData.atomDataIterator();
       while( eDataIt.hasNext() ){
           eData = eDataIt.next();
           this.addEdge( eData.origin(), eData.destination(), eData.type());
       }
       return graph;
   }
    
   private void addVertex( String name, VertexType vertexType ){
       vertexCount++;
       Vertex vert = new Vertex(vertexCount, name, vertexType, sourceRef);
       insertedVertices.put(name, vert);
       graph.addVertex(vert);
   }
   
   private void addEdge( String origin, String destination, EdgeType edgeType ){
       edgeCount++;
       Edge edge = new Edge( edgeCount, edgeType, sourceRef );
       graph.addEdge(edge, insertedVertices.get(origin), insertedVertices.get(destination));
   }
    
}
